分享一个近期遇到的 Linux 问题,涉及多个模块

🔍 溯源 ✍️ Jason | 📅 2026-04-14 | 👍 2 | 原帖↗
#知识星球 #立芯嵌入式 #来源/立芯星球 #技术/Linux调试 #技术/调度 #质量/精华

原帖 | Jason | 2026-04-14 17:00 | 👍2 | 阅读约1

分享一个近期遇到的 Linux 问题,涉及多个模块:蓝牙、串口、dma、中断下半部、中断线程化、trace、coredump 解析、调度机制、backtrace 等,深度考察你的综合能力。

问题现象:蓝牙模块重启,重启原因是蓝牙模块运行需要串口数据,但是两秒内没有收到串口数据。

串口 owner 分析:从 log 看 uart dma tx 发送数据发不出去,自然收不到外设回复。发不出去的原因是 uart dma tx irq thread 中断线程得不到 cpu 调度,看起来是性能问题。

找到问题现场 trace(perfetto 版本),发现 cpu0 一直被 kworker 和 ksoftirqd 占用,并且它俩还关闭了抢占,导致 uart dma tx 的 irq thread 无法运行。但是 kworker 和 ksoftirqd 是 Linux 内核处理 workqueue 和软中断的公共线程,如果他们不吐 log,我们就找不到凶手是谁。分析陷入了停滞。

换个思路,我们是八核 CPU,有看到其他 cpu 有 napi thread 在跑,百度后发现是网络处理的相关线程,从 trace 看 napi thread 跑一次也要很久,很明显也关了 cpu 抢占。然后又看到另外一份 HWT 死机的 coredump 文件,解析后发现是 cpu0 不喂狗触发的,这里的 backtrace 发现了 net 的相关函数。

至此我们高度怀疑,是网络有大量数据要处理,占满 kworker 和 ksoftirqd 内核线程,它们关了 CPU 抢占导致其他线程无法运行,至此找到了凶手。

背景:uart dma tx 的 irq thread 为什么一定要等 cpu0 ?因为 Linux 默认哪个 cpu 响应了 irq,那这个 irq 的下半部就在哪个 cpu 跑。

这题表面上是蓝牙模块重启,实际上是网络模块处理大量数据导致整机卡顿,是性能问题。所以很多时候你看到的问题不是你的问题,你只是受害者(进程调度的摆核/调频/调度三层框架见 进程调度 在所有操作系统中都很重要,不管是 FreeRTOS 还)。


相关笔记